﻿using Comm100.Framework.Domain.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bot.Domain.Entities;
using Bot.Domain.Interfaces;
using Bot.Domain.Bo;
using Castle.Windsor;
using Bot.Domain.Specifications;
using Bot.Domain.BotImport;
using Bot.Domain.Bot;
using AutoMapper;
using Newtonsoft.Json;
using System.Data;
using Bot.Domain.Enum;
using System.IO;
using Bot.Infrastructure;
using System.Text.RegularExpressions;

namespace Bot.Domain.Categories.Service
{
    public class IntentDomainService : IIntentDomainService
    {
        private IWindsorContainer _container;
        private readonly IRepository<Guid, Intent> _repository;
        public IMapper Mapper { get; set; }

        public IntentDomainService(IRepository<Guid, Intent> repository, IWindsorContainer container)
        {
            this._repository = repository;
            this._container = container;
        }

        public Intent Create(Guid botId, Intent intent)
        {
            if(intent.Id == Guid.Empty)
            {
                intent.Id = Guid.NewGuid();
            }

            if (intent.Questions!=null&& intent.Questions.Count > 0)
            {
                IIntentQuestionDomainService intentQuestionDomainService = _container.Resolve<IIntentQuestionDomainService>();
                foreach(var question in intent.Questions)
                {
                    question.IntentId = intent.Id;
                    intentQuestionDomainService.Create(question);
                }  
            }
            if(intent.AnswerInChannels!=null&& intent.AnswerInChannels.Count > 0)
            {
                IIntentAnswerInChannelDomainService intentAnswerInChannelDomainService = _container.Resolve<IIntentAnswerInChannelDomainService>();
                foreach(var answerInChannel in intent.AnswerInChannels)
                {
                    answerInChannel.IntentId = intent.Id;
                    intentAnswerInChannelDomainService.Create(answerInChannel);
                }
            }

            //调用引擎服务
            IBotApiService botApiService = _container.Resolve<IBotApiService>();
            IChatbotDomainService chatbotDomainService = _container.Resolve<IChatbotDomainService>();
            var chatbot = chatbotDomainService.Get(botId);
            var botDto = Mapper.Map<BotDto>(chatbot);
            var intentDto = Mapper.Map<IntentDto>(intent);
            var mappingToDialogflowId = botApiService.CreateIntent(intentDto, botDto).Result;
            intent.MappingToDialogflowId = mappingToDialogflowId;

            return _repository.Create(intent);
        }

        public Intent Get(Guid id, string include = "")
        {
            var intent = _repository.Get(id);

            if (intent != null && !string.IsNullOrEmpty(include))
            {
                IntentIncludeEntity(intent, include);
            }
            
            return intent;
        }

        public Intent Update(IntentUpdateBo bo)
        {
            Intent intent = _repository.Get(bo.Id);

            IIntentQuestionDomainService intentQuestionDomainService = _container.Resolve<IIntentQuestionDomainService>();
            IIntentAnswerInChannelDomainService intentAnswerInChannelDomainService = _container.Resolve<IIntentAnswerInChannelDomainService>();

            var questionIds = new List<Guid> { };

            if (bo.Questions != null && bo.Questions.Count > 0)
            {
                foreach (var questionBo in bo.Questions)
                {      
                    if (questionBo.Id == Guid.Empty)
                    {
                        //新增
                        questionBo.IntentId = intent.Id;
                        questionBo.Id = Guid.NewGuid();

                        var question = Mapper.Map<IntentQuestion>(questionBo);
                        intentQuestionDomainService.Create(question);
                        questionIds.Add(questionBo.Id);
                    }      
                    else
                    {
                        //修改
                        questionBo.IntentId = bo.Id;
                        intentQuestionDomainService.Update(questionBo);
                        questionIds.Add(questionBo.Id);
                    }
                }
            }
            //删除
            var questions = intentQuestionDomainService.GetByIntentId(bo.Id);
            foreach(var question in questions)
            {
                if (!questionIds.Contains(question.Id))
                {
                    intentQuestionDomainService.Delete(question.Id);
                }
            }

            var answerInChannelIds = new List<Guid> { };

            if (bo.AnswerInChannels != null && bo.AnswerInChannels.Count > 0)
            {
                foreach (var answerInChannelBo in bo.AnswerInChannels)
                {
                    if(answerInChannelBo.Id == Guid.Empty)
                    {
                        //新增
                        answerInChannelBo.Id = Guid.NewGuid();
                        answerInChannelBo.IntentId = bo.Id;
                        var answerInChannel = Mapper.Map<IntentAnswerInChannel>(answerInChannelBo);

                        intentAnswerInChannelDomainService.Create(answerInChannel);
                        answerInChannelIds.Add(answerInChannelBo.Id);
                    }
                    else
                    {
                        //修改
                        answerInChannelBo.IntentId = bo.Id;
                        intentAnswerInChannelDomainService.Update(answerInChannelBo);
                        answerInChannelIds.Add(answerInChannelBo.Id);
                    }
          
                }
            }
            //删除
            var answerInChannels = intentAnswerInChannelDomainService.GetByIntentId(bo.Id);
            if(answerInChannels!=null
                && answerInChannels.Count() > 0)
            {
                foreach(var answerInChannel in answerInChannels)
                {
                    if (!answerInChannelIds.Contains(answerInChannel.Id))
                    {
                        intentAnswerInChannelDomainService.Delete(answerInChannel.Id);
                    }
                }
            }

            intent.Id = bo.Id;
            intent.CategoryId = bo.CategoryId;
            intent.Name = bo.Name;

            _repository.Update(intent);

            return Get(intent.Id, "questions,answerInChannels,responses,form,fields,prompts,selectedKeywords");

        }

        public IEnumerable<Intent> List(Guid botId, string include, Guid? categoryId, string keyword)
        {
            IEnumerable<Intent> list = new List<Intent> { };
            if (categoryId.HasValue)
            {
                list = _repository.List(new IntentFilterSpecification(categoryId.Value)).ToList();
            }
            else
            {
                //所有的
                ICategoryDomainService categoryDomainService = _container.Resolve<ICategoryDomainService>();
                var categorys = categoryDomainService.GetByBotId(botId);
                if(categorys!=null&& categorys.Count > 0)
                {
                    foreach(var category in categorys)
                    {
                        var intents = _repository.List(new IntentFilterSpecification(category.Id)).ToList();
                        if(intents!=null&& intents.Count > 0)
                        {
                            list = list.Concat(intents);
                        }            
                    }
                }
            }

            if (!string.IsNullOrEmpty(keyword))
            {
                list = list.Where(f => f.Name.Contains(keyword, StringComparison.OrdinalIgnoreCase) ||
                    f.Questions.Any(a => a.Content.Contains(keyword, StringComparison.OrdinalIgnoreCase)));
            }

            if (list != null && list.Count() > 0 && !string.IsNullOrEmpty(include))
            {
                foreach (var intent in list)
                {
                    IntentIncludeEntity(intent, include);
                }
            }

            return list;
        }

        public void Delete(Guid id)
        {
            Intent intent = _repository.Get(id);
            //删除子表
            IIntentQuestionDomainService intentQuestionDomainService = _container.Resolve<IIntentQuestionDomainService>();
            IIntentAnswerInChannelDomainService intentAnswerInChannelDomainService = _container.Resolve<IIntentAnswerInChannelDomainService>();

            var questions = intentQuestionDomainService.GetByIntentId(id);
            if (questions != null && questions.Count > 0)
            {
                foreach (var question in questions)
                {
                    intentQuestionDomainService.Delete(question.Id);
                }
            }

            var answers = intentAnswerInChannelDomainService.GetByIntentId(id);
            if (answers != null && answers.Count() > 0)
            {
                foreach (var answer in answers)
                {
                    intentAnswerInChannelDomainService.Delete(answer.Id);
                }
            }

            _repository.Delete(intent);

        }

        public bool NameCheck(Guid botId, string name)
        {
            ICategoryDomainService categoryDomainService = _container.Resolve<ICategoryDomainService>();
            var categorys = categoryDomainService.GetByBotId(botId);
            if(categorys!=null
                && categorys.Count > 0)
            {
                var count = _repository.Count(new IntentFilterSpecification(categorys.Select(a => a.Id).ToList(), name));
                return count == 0;
            }

            return true;
            
        }

        public List<Intent> GetByCategoryIds(List<Guid> categoryIds)
        {
            return _repository.List(new IntentFilterSpecification(categoryIds)).ToList();
        }

        public List<Intent> GetByCategoryId(Guid categoryId, string include="")
        {
            var intents = _repository.List(new IntentFilterSpecification(categoryId)).ToList();
            if (intents != null
                && intents.Count > 0
                && !string.IsNullOrEmpty(include))
            {
                foreach(var intent in intents)
                {
                    IntentIncludeEntity(intent, include);
                }
            }
            return intents;
        }

        public Operation Import(Guid jobId, string filePath, Chatbot bot, EnumImportMode mode)
        {
            Operation operation = new Operation { };
            var result = ImportIntent(jobId, filePath, bot, mode);
            if (result.Status == EnumImportHandleStatus.Failed)
            {
                operation.Status = EnumOperationStatus.Failed;
                operation.ErrorMessage = result.ErrorMessage;
            }
            else if (result.Status == EnumImportHandleStatus.Succeeded)
            {
                operation.Status = EnumOperationStatus.Succeeded;
            }
            else
            {
                operation.Status = EnumOperationStatus.Processing;
            }

            return operation;
        }
        public List<IntentScore> QueryTopScore(Guid botId, string question, int top = 10)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// query intent
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="detectIntentRequestBody"></param>
        /// <returns></returns>
        public DetectIntentResponse DetectIntent(Guid sessionId, DetectIntentRequestBody detectIntentRequestBody)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// goto intent
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="triggerAnIntentRequestBody"></param>
        /// <returns></returns>
        public TriggerAnIntentResponse TriggerAnIntent(Guid sessionId, TriggerAnIntentRequestBody triggerAnIntentRequestBody)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// via form
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="submitFormRequestBodyDto"></param>
        /// <returns></returns>
        public HighConfidenceAnswer SubmitForm(Guid sessionId, SubmitFormRequestBody submitFormRequestBodyDto)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// authentication
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="submitAuthenticationRequestBody"></param>
        /// <returns></returns>
        public HighConfidenceAnswer SubmitAuthentication(Guid sessionId, SubmitAuthenticationRequestBody submitAuthenticationRequestBody)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// location
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="submitLocationRequestBody"></param>
        /// <returns></returns>
        public HighConfidenceAnswer SubmitLocation(Guid sessionId, SubmitLocationRequestBody submitLocationRequestBody)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// rate
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="rateRequestBody"></param>
        /// <returns></returns>
        public NotHelpfulAnswer Rate(Guid sessionId, RateRequestBody rateRequestBody)
        {
            throw new NotImplementedException();
        }

        public Intent GetByName(Guid botId, string name)
        {
            ICategoryDomainService categoryDomainService = _container.Resolve<ICategoryDomainService>();
            var categoryIds = categoryDomainService.GetByBotId(botId).Select(a=>a.Id).ToList();
            var intents = _repository.List(new IntentFilterSpecification(categoryIds, name));
            return intents.FirstOrDefault();
        }

        public IEnumerable<AnswerInChannelPrompt> GetPromptsByIntentId(Guid intentId)
        {
            var intent = Get(intentId, "answerInChannels,prompts");
            if(intent.AnswerInChannels!=null&& intent.AnswerInChannels.Any(a => a.Prompts != null && a.Prompts.Count > 0))
            {
                return intent.AnswerInChannels.FirstOrDefault(a => a.Prompts != null && a.Prompts.Count > 0).Prompts;
            }

            return null;
        }

        public IEnumerable<Response> GetResponsesByIntentId(Guid intentId)
        {
            var intent = Get(intentId, "answerInChannels,responses");
            return intent.AnswerInChannels.SelectMany(a => a.Responses);
        }

        #region private
        private void IntentIncludeEntity(Intent intent, string include = "")
        {
            if (!string.IsNullOrEmpty(include) && include.Split(',').Contains("category"))
            {
                ICategoryDomainService categoryDomainService = _container.Resolve<ICategoryDomainService>();
                intent.Category = categoryDomainService.Get(intent.CategoryId);
            }
            if (!string.IsNullOrEmpty(include) && include.Split(',').Contains("questions"))
            {
                IIntentQuestionDomainService intentQuestionDomainService = _container.Resolve<IIntentQuestionDomainService>();
                intent.Questions = intentQuestionDomainService.GetByIntentId(intent.Id, include);
            }
            if (!string.IsNullOrEmpty(include) && include.Split(',').Contains("answerInChannels"))
            {
                IIntentAnswerInChannelDomainService intentAnswerInChannelDomainService = _container.Resolve<IIntentAnswerInChannelDomainService>();
                intent.AnswerInChannels = intentAnswerInChannelDomainService.GetByIntentId(intent.Id, include).ToList();
            }
        }
        #endregion
        #region 导入业务逻辑
        public ImportResult ImportIntent(Guid jobId, string filePath, Chatbot bot, EnumImportMode mode)
        {
            string xmlFilePath = filePath;

            EnumImportHandleStatus handleStatus = EnumImportHandleStatus.Busy;
            IList<string> errorMessages = new List<string>();

            BackgroundJob backgroundJob = null;
            IntentImportDataQueue intentImportDataQueue = GetImportDataQueue(jobId, xmlFilePath, bot, mode, out backgroundJob);
            IBotApiService botApiService = _container.Resolve<IBotApiService>();
            try
            {
                if (intentImportDataQueue.ProcessState == EnumOperationStatus.Occupy)
                {
                    //线程处理中
                    handleStatus = EnumImportHandleStatus.Busy;
                }
                else
                {
                    switch (intentImportDataQueue.Status)
                    {
                        case EnumImportHandleStatus.Wait:
                            {
                                intentImportDataQueue.ProcessId = 1;
                                string errorMessage = "";
                                List<IntentImportDto> intentImportDtoList = null;
                                errorMessage = handleFile(filePath, bot, mode, out intentImportDtoList);
                                if (!string.IsNullOrEmpty(errorMessage))
                                {
                                    //存在错误
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51293;
                                    string message = APIHelper.GetErrorMessageByCode(intentImportDataQueue.ErrorCode)?.Message;
                                    if (!string.IsNullOrEmpty(message))
                                    {
                                        message = string.Format(message, string.Join(",", errorMessages));
                                        intentImportDataQueue.ErrorMessages = new string[] { message };
                                    }
                                }
                                else
                                {
                                    intentImportDataQueue.Status = EnumImportHandleStatus.CheckData;
                                    intentImportDataQueue.IntentImportDtoList = intentImportDtoList;

                                    if (mode == EnumImportMode.increment)
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.DeleteBotInfo;
                                    }
                                }
                                break;
                            }
                        case EnumImportHandleStatus.CheckData:
                            {
                                intentImportDataQueue.ProcessId = 2;
                                string errorMessage = "";
                                ApiResult apiResult = DeleteEngineInfo(bot);
                                if (!apiResult.IsSuccess)
                                {
                                    //存在错误
                                    errorMessage = apiResult.Error.Message;
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51294;
                                }
                                else
                                {
                                    if (apiResult.Data != null)
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.DeleteEngineInfoProceeing;
                                        intentImportDataQueue.OperationName = apiResult.Data.ToString();
                                    }
                                    else
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.DeleteEngineInfoCompleted;
                                    }
                                }
                                break;
                            }
                        case EnumImportHandleStatus.DeleteEngineInfoProceeing:
                            {
                                intentImportDataQueue.ProcessId = 2;
                                string errorMessage = "";

                                int siteId = bot.SiteId;
                                Guid botId = bot.Id;
                                string name = intentImportDataQueue.OperationName;
                                var botDto = Mapper.Map<BotDto>(bot);
                                ApiResult apiResult = botApiService.GetOperations(botDto, name).Result;

                                if (!apiResult.IsSuccess)
                                {
                                    //存在错误
                                    errorMessage = apiResult.Error.Message;
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51295;
                                }
                                else
                                {
                                    if (apiResult.Data != null)
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.DeleteEngineInfoProceeing;
                                        intentImportDataQueue.OperationName = apiResult.Data.ToString();
                                    }
                                    else
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.DeleteEngineInfoCompleted;
                                    }
                                }

                                break;
                            }
                        case EnumImportHandleStatus.DeleteEngineInfoCompleted:
                            {
                                intentImportDataQueue.ProcessId = 3;
                                string errorMessage = "";
                                errorMessage = DeleteBotCategory(bot.SiteId, bot.Id);

                                if (!string.IsNullOrEmpty(errorMessage))
                                {
                                    //存在错误
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51296;
                                }
                                else
                                {
                                    intentImportDataQueue.Status = EnumImportHandleStatus.DeleteBotInfo;
                                }
                                break;
                            }
                        case EnumImportHandleStatus.DeleteBotInfo:
                            {
                                intentImportDataQueue.ProcessId = 4;
                                string errorMessage = "";

                                List<IntentImportDto> noErrorIntentImportDto = intentImportDataQueue.IntentImportDtoList.Where(a => a.ErrorMsg.Length == 0).ToList();
                                errorMessage = CreateBotCategory(bot, noErrorIntentImportDto, mode);

                                if (!string.IsNullOrEmpty(errorMessage))
                                {
                                    //存在错误
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51297;
                                }
                                else
                                {
                                    ApiResult apiResult = ImportIntentByEngine(intentImportDataQueue, bot);

                                    if (!apiResult.IsSuccess)
                                    {
                                        //存在错误
                                        errorMessage = apiResult.Error.Message;
                                        intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                        errorMessages.Add(errorMessage);
                                        intentImportDataQueue.ErrorMessages = errorMessages;
                                        intentImportDataQueue.ErrorCode = 51298;
                                    }
                                    else
                                    {
                                        if (apiResult.Data != null)
                                        {
                                            intentImportDataQueue.Status = EnumImportHandleStatus.BotEngineImportProceeing;
                                            intentImportDataQueue.OperationName = apiResult.Data.ToString();
                                        }
                                        else
                                        {
                                            intentImportDataQueue.Status = EnumImportHandleStatus.BotEngineImportCompleted;
                                        }
                                    }
                                }

                                break;
                            }
                        case EnumImportHandleStatus.BotEngineImportProceeing:
                            {
                                intentImportDataQueue.ProcessId = 4;
                                string errorMessage = "";

                                int siteId = bot.SiteId;
                                Guid botId = bot.Id;
                                string name = intentImportDataQueue.OperationName;
                                var botDto = Mapper.Map<BotDto>(bot);
                                ApiResult apiResult = botApiService.GetOperations(botDto, name).Result;

                                if (!apiResult.IsSuccess)
                                {
                                    //存在错误
                                    errorMessage = apiResult.Error.Message;
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51295;
                                }
                                else
                                {
                                    if (apiResult.Data != null)
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.BotEngineImportProceeing;
                                        intentImportDataQueue.OperationName = apiResult.Data.ToString();
                                    }
                                    else
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.BotEngineImportCompleted;
                                    }
                                }
                                break;
                            }
                        case EnumImportHandleStatus.BotEngineImportCompleted:
                            {
                                intentImportDataQueue.ProcessId = 5;
                                string errorMessage = InitDataWithBotEngine(intentImportDataQueue, bot);
                                if (!string.IsNullOrEmpty(errorMessage))
                                {
                                    //存在错误
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51299;
                                }
                                else
                                {
                                    intentImportDataQueue.Status = EnumImportHandleStatus.InitDataWithBotEngine;
                                }

                                break;
                            }
                        case EnumImportHandleStatus.InitDataWithBotEngine:
                            {
                                intentImportDataQueue.ProcessId = 6;
                                //数据队列化 ,缓存到内存中
                                string errorMessage = ImportData2Queue(intentImportDataQueue);
                                if (!string.IsNullOrEmpty(errorMessage))
                                {
                                    //存在错误
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51300;
                                }
                                else
                                {
                                    intentImportDataQueue.Status = EnumImportHandleStatus.ImportData2Queue;
                                }

                                break;
                            }
                        case EnumImportHandleStatus.ImportData2Queue:
                        case EnumImportHandleStatus.Processing:
                            {
                                intentImportDataQueue.ProcessId = 7;
                                string errorMessage = SaveDbForImportData(intentImportDataQueue, bot);
                                if (!string.IsNullOrEmpty(errorMessage))
                                {
                                    //存在错误
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51301;
                                }

                                break;
                            }
                        case EnumImportHandleStatus.Publish:
                            {
                                intentImportDataQueue.ProcessId = 8;
                                string errorMessage = string.Empty;
                                //errorMessage = await PublishBot(appId, versionId, botId, luis);
                                int siteId = bot.SiteId;
                                string operationId = intentImportDataQueue.OperationId;
                                ApiResult apiResult = GetErrorIntentImportExcelPath(intentImportDataQueue.FileName, intentImportDataQueue.IntentImportDtoList, siteId, jobId);
                                if (apiResult.IsSuccess)
                                {
                                    if (apiResult.Data != null && !string.IsNullOrEmpty(apiResult.Data.ToString()))
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                        intentImportDataQueue.FailedPath = apiResult.Data.ToString();
                                    }
                                    else
                                    {
                                        intentImportDataQueue.Status = EnumImportHandleStatus.Succeeded;
                                    }

                                }
                                else
                                {
                                    errorMessage = apiResult.Error.Message;
                                    intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
                                    errorMessages.Add(errorMessage);
                                    intentImportDataQueue.ErrorMessages = errorMessages;
                                    intentImportDataQueue.ErrorCode = 51302;
                                }
                                break;
                            }
                        default:
                            break;
                    }

                    handleStatus = intentImportDataQueue.Status;
                }
            }
            catch (Exception e)
            {
                errorMessages.Add(e.Message);
                intentImportDataQueue.ErrorMessages = errorMessages;
                LogHelper.Error(JsonConvert.SerializeObject(e));
                handleStatus = EnumImportHandleStatus.Failed;
                intentImportDataQueue.Status = EnumImportHandleStatus.Failed;
            }
            finally
            {
                if (intentImportDataQueue.ProcessState == EnumOperationStatus.Free)
                {
                    intentImportDataQueue.ProcessState = EnumOperationStatus.Free;
                    SetImportDataQueue(jobId, filePath, intentImportDataQueue, bot, mode);
                }
            }

            if (handleStatus == EnumImportHandleStatus.Failed)
            {//为了让下一次调用接口时候，返回上次的错误消息
                errorMessages = intentImportDataQueue.ErrorMessages;

                //LogHelper.Error(JsonConvert.SerializeObject(new
                //{
                //    Processed = intentImportDataQueue.ProcessId,
                //    Status = handleStatus.ToString(),
                //    ErrorMessage = string.Join(",", errorMessages)
                //}));
            }

            return new ImportResult
            {
                Processed = intentImportDataQueue.ProcessId,
                Total = 8,
                Status = handleStatus,
                ErrorMessage = string.Join(",", errorMessages),
                FailUrl = intentImportDataQueue.FailedPath,
                OperationId = intentImportDataQueue.OperationId,
                ErrorCode = intentImportDataQueue.ErrorCode,
            };
        }

        private string handleFile(string filePath, Chatbot bot, EnumImportMode mode, out List<IntentImportDto> intentImportDtoList)
        {
            ICategoryDomainService categoryDomainService = _container.Resolve<ICategoryDomainService>();
            IIntentDomainService intentDomainService = _container.Resolve<IIntentDomainService>();
            IIntentQuestionDomainService intentQuestionDomainService = _container.Resolve<IIntentQuestionDomainService>();

            intentImportDtoList = new List<IntentImportDto>();

            DataTable dataTable = null;
            string errorMsg = CheckFile(filePath, out dataTable);
            if (!string.IsNullOrEmpty(errorMsg))
            {
                return errorMsg;
            }

            if (dataTable != null && dataTable.Rows.Count > 0)
            {
                if (!dataTable.Columns.Contains("Category Path"))
                    return "Column [Category Path] is required.";
                if (!dataTable.Columns.Contains("Intent Name"))
                    return "Column [Intent Name] is required.";
                if (!dataTable.Columns.Contains("Response"))
                    return "Column [Response] is required.";
                if (!dataTable.Columns.Contains("Visitor Questions"))
                    return "Column [Visitor Questions] is required.";

                bool ifExistsQuickReply = false;
                if (dataTable.Columns.Contains("Quick Reply"))
                {//2019.7.25回答是否包含QuickReply
                    ifExistsQuickReply = true;
                }

                List<Intent> botIntentsList = null;
                List<IntentQuestion> intentQuestionsList = null;
                if (mode == EnumImportMode.increment)
                {
                    //增量模式导入
                    botIntentsList = intentDomainService.List(bot.Id, "", null, "").ToList();
                    List<Guid> intentIdList = botIntentsList.Select(a => a.Id).ToList();
                    intentQuestionsList = intentQuestionDomainService.GetByIntentIds(intentIdList).ToList();
                }

                Dictionary<string, List<IntentImportDto>> dicIntentImportDtoList = new Dictionary<string, List<IntentImportDto>>();

                foreach (DataRow row in dataTable.Rows)
                {
                    if (string.IsNullOrWhiteSpace(row["Category Path"].ToString()) && string.IsNullOrWhiteSpace(row["Intent Name"].ToString()) && string.IsNullOrWhiteSpace(row["Visitor Questions"].ToString()) && string.IsNullOrWhiteSpace(row["Response"].ToString()))
                        continue;

                    string categoryPath = row["Category Path"].ToString();
                    string intentName = row["Intent Name"].ToString().Trim();
                    string visitorQuestions = row["Visitor Questions"].ToString();
                    string response = row["Response"].ToString();
                    string errMsg = row.Table.Columns.Contains("Error Message") ? row["Error Message"].ToString() : "";
                    Guid catagoryId = Guid.Empty;
                    bool ifExsitsIntent = false;
                    string quickReply = "";

                    if (ifExistsQuickReply)
                    {
                        quickReply = row["Quick Reply"].ToString();
                    }

                    if (string.IsNullOrEmpty(errMsg))
                    {
                        if (string.IsNullOrEmpty(categoryPath))
                        {
                            errMsg += string.Format("{0} is required.", "Category Path");
                        }

                        if (string.IsNullOrEmpty(intentName))
                        {
                            errMsg += string.Format("{0} is required.", "Intent Name");
                        }
                        else
                        {
                            if (intentName.Length > 100)
                            {
                                errMsg += string.Format("{0}", "The Intent Name length cannot exceed the limit 100.");
                            }
                            if (intentName.Trim().ToUpperInvariant().Equals("DEFAULT"))
                            {
                                errMsg += string.Format("{0}", "The Intent Name cannot be default.");
                            }
                            Regex rgx = new Regex("[\\n\\r\\t]");
                            if (rgx.IsMatch(intentName))
                            {
                                errMsg += string.Format("{0}", "The Intent Name contains illegal characters.");
                            }

                        }

                        if (string.IsNullOrEmpty(visitorQuestions))
                        {
                            errMsg += string.Format("{0} is required.", "Visitor Questions");
                        }
                        else
                        {
                            //去重
                            visitorQuestions = string.Join("|", Utils.TextSplitTrim(visitorQuestions, "|"));
                            string[] questions = visitorQuestions.Split('|').Select(s => Regex.Replace(s.Trim('\n'), "([,.?!:;])", " $0 ", RegexOptions.IgnoreCase | RegexOptions.Multiline)).Where(w => !string.IsNullOrWhiteSpace(w)).Distinct().ToArray();

                            if (mode == EnumImportMode.increment)
                            {
                                //增量模式导入
                                var botIntents = botIntentsList?.FirstOrDefault(a => a.Name == intentName);
                                if (botIntents != null)
                                {
                                    ifExsitsIntent = true;
                                    var intentQuestionsFindList = intentQuestionsList?.Where(a => a.IntentId == botIntents.Id).ToList();
                                    if (intentQuestionsFindList != null)
                                    {
                                        //取差集

                                        questions = questions.Except(intentQuestionsFindList.Select(a => a.Content)).ToArray();
                                    }
                                }

                                //BotIntents botIntents = intentDomainService.GetByName(bot.Id, intentName);
                                //if(botIntents!=)
                            }

                            visitorQuestions = string.Join("|", questions);
                            if (questions.Count() > 2000)
                            {
                                errMsg += string.Format("{0}", "The Visitor Questions cannot exceed the limit 2000 each Intent.");
                            }
                            foreach (string q in questions)
                            {
                                if (Encoding.UTF8.GetByteCount(q) > 768)
                                {
                                    errMsg += string.Format("{0}", "Each Question's length cannot exceed the limit 768.");
                                    break;
                                }
                            }
                        }
                        if (string.IsNullOrEmpty(response))
                        {
                            errMsg += string.Format("{0} is required.", "Response");
                        }

                        if (!string.IsNullOrEmpty(categoryPath))
                        {
                            string categoryName = categoryPath;
                            if (categoryPath.Equals("/"))
                            {

                            }
                            else
                            {
                                string[] categoryPathArr = categoryPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                                categoryName = categoryPathArr.Last();
                            }

                            var botCatagory = categoryDomainService.GetCatagoriesByBotIdAndName(bot.Id, categoryName);
                            if (botCatagory != null)
                            {
                                catagoryId = botCatagory.Id;
                            }
                            else
                            {

                                //创建Category
                                //CreateCategory(bot.SiteId, bot.Id, categoryPath);
                                //errMsg += string.Format("[{0}] BotCatagory not exist.", categoryPath);
                            }
                        }

                        //if (intentAppService.NameCheck(-1, bot.Id, intentName) && intentName.ToLower().Trim() != "none")
                        //{

                        //}
                        //else
                        //{
                        //    errMsg += string.Format("Intent with the same name already exists.");
                        //}
                    }

                    IntentImportDto intentImportDto = new IntentImportDto()
                    {
                        CategoryPath = categoryPath,
                        CategoryId = catagoryId,
                        IntentName = intentName,
                        VisitorQuestions = visitorQuestions,
                        Response = response,
                        ErrorMsg = errMsg,
                        Mode = mode,
                        IfExsitsIntent = ifExsitsIntent,
                        QuickReply = quickReply,
                    };

                    //intentImportDtoList.Add(intentImportDto);
                    if (dicIntentImportDtoList.Keys.Contains(intentName))
                    {
                        //删除之前存在的同名Intent
                        //dicIntentImportDtoList.Remove(intentName);
                        foreach (IntentImportDto intentDto in dicIntentImportDtoList[intentName])
                        {
                            intentDto.ErrorMsg = "intent duplicated";
                        }
                    }
                    else
                    {
                        dicIntentImportDtoList.Add(intentName, new List<IntentImportDto>());
                    }

                    dicIntentImportDtoList[intentName].Add(intentImportDto);
                }

                foreach (List<IntentImportDto> list in dicIntentImportDtoList.Values)
                {
                    intentImportDtoList.AddRange(list);
                }
            }
            else
                errorMsg = "No data to import";
            return errorMsg;
        }
        private string CheckFile(string filePath, out DataTable dataTable)
        {
            string errorMsg = "";
            dataTable = null;

            string[] fileExtensions = new string[] { ".xls", ".xlsx", ".csv" };
            if (File.Exists(filePath))
            {
                FileInfo fileInfo = new FileInfo(filePath);
                string extension = fileInfo.Extension;
                decimal fileSize = Math.Round(decimal.Divide(fileInfo.Length, 1024 * 1024), 2);

                if (!fileExtensions.Contains(extension))
                {
                    errorMsg = "Invalid file type.";
                }
                else if (fileSize > 10)
                {
                    errorMsg = "The file size should be less than 10MB.";
                }
                else
                {
                    var util = TransferDataFactory.GetUtil(filePath);

                    try
                    {
                        dataTable = util.GetData(filePath);
                    }
                    catch (Exception e)
                    {
                        errorMsg = "Invalid file.";
                    }

                    if (dataTable != null && dataTable.Rows.Count > 1000)
                    {
                        errorMsg = "You can only import less than 1000 Intents at a time.";
                    }
                    else
                    {

                    }
                }
            }
            else
            {
                errorMsg = "File not exist";
            }

            return errorMsg;
        }

        private ApiResult DeleteEngineInfo(Chatbot bot)
        {
            ApiResult apiResult = new ApiResult { IsSuccess = false };
            try
            {
                IBotApiService botApiService = _container.Resolve<IBotApiService>();
                var botDto = Mapper.Map<BotDto>(bot);
                List<IntentModelAggregate> intentModelAggregateList = botApiService.GetIntentList(botDto).Result;
                if (intentModelAggregateList != null && intentModelAggregateList.Count > 0)
                {
                    string[] MappingToBotEngines = intentModelAggregateList.Select(a => a.IntentModel.Id).ToArray();
                    apiResult = botApiService.BatchDeleteIntents(botDto, MappingToBotEngines).Result;
                }
                else
                {
                    apiResult.IsSuccess = true;
                }
            }
            catch (Exception e)
            {
                apiResult.Error = new ErrorInfo
                {
                    Message = e.Message
                };
                LogHelper.Error(JsonConvert.SerializeObject(e));
            }

            finally
            {

            }
            return apiResult;
        }

        private string DeleteBotCategory(int siteId, Guid botId)
        {
            string errorMessage = "";
            try
            {
                ICategoryDomainService categoryDomainService = _container.Resolve<ICategoryDomainService>();
                IIntentDomainService intentDomainService = _container.Resolve<IIntentDomainService>();

                var listIntentsToDelete = intentDomainService.List(botId, "", null, "");
                if (listIntentsToDelete != null && listIntentsToDelete.Count() > 0)
                {
                    foreach (var botIntent in listIntentsToDelete)
                    {
                        //删除 t_Bot_BotIntents
                        intentDomainService.Delete(botIntent.Id);
                    }
                }

                //删除 t_Bot_BotCatagory
                var botCatagoryList = categoryDomainService.GetByBotId(botId);
                if (botCatagoryList != null)
                {
                    for (var i = 0; i < botCatagoryList.Count; i++)
                    {
                        categoryDomainService.Delete(botCatagoryList[i].Id);
                    }
                }

            }
            catch (Exception e)
            {
                errorMessage = e.Message;
                LogHelper.Error(JsonConvert.SerializeObject(e));
            }
            finally
            {

            }

            return errorMessage;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="siteId"></param>
        /// <param name="botId"></param>
        /// <param name="mode"></param>
        private string CreateBotCategory(Chatbot bot, List<IntentImportDto> intentImportDtoList, EnumImportMode mode)
        {
            string errorMessage = "";
            try
            {
                ICategoryDomainService categoryDomainService = _container.Resolve<ICategoryDomainService>();
                foreach (IntentImportDto intentImportDto in intentImportDtoList)
                {
                    if (string.IsNullOrWhiteSpace(intentImportDto.ErrorMsg) && !(intentImportDto.Mode == EnumImportMode.increment && intentImportDto.IfExsitsIntent))
                    {
                        string categoryPath = intentImportDto.CategoryPath;
                        //创建Category
                        Guid categoryId = categoryDomainService.CreateCategory(bot.Id, categoryPath);
                        intentImportDto.CategoryId = categoryId;
                    }
                }
            }
            catch (Exception e)
            {
                errorMessage = e.Message;
                LogHelper.Error(JsonConvert.SerializeObject(e));
            }
            finally
            {

            }

            return errorMessage;
        }

        private ApiResult ImportIntentByEngine(IntentImportDataQueue intentImportDataQueue, Chatbot bot)
        {
            ApiResult apiResult = new ApiResult { IsSuccess = true };
            try
            {
                IBotApiService botApiService = _container.Resolve<IBotApiService>();

                List<BotIntentTypeEx> botIntentTypeExList = new List<BotIntentTypeEx>();
                if (intentImportDataQueue.IntentImportDtoList != null && intentImportDataQueue.IntentImportDtoList.Count > 0)
                {
                    //只处理没有错误的数据
                    List<IntentImportDto> noErrorIntentImportDto = intentImportDataQueue.IntentImportDtoList.Where(a => a.ErrorMsg.Length == 0).ToList();
                    BotImportDataQueue botImportDataQueue = GetBotImportDataQueue(bot, noErrorIntentImportDto);
                    if (botImportDataQueue != null)
                    {
                        var botDto = Mapper.Map<BotDto>(bot);
                        apiResult = botApiService.ImportBot(botDto,botImportDataQueue).Result;
                    }
                    //foreach (IntentImportDto intentImportDto in noErrorIntentImportDto)
                    //{
                    //    List<BotIntentQuestionTypeEx> botIntentQuestionTypeExList = new List<BotIntentQuestionTypeEx>();

                    //    string[] questions = Utils.TextSplitTrim(intentImportDto.VisitorQuestions, "|");
                    //    Array.ForEach(questions, (question) =>
                    //    {
                    //        botIntentQuestionTypeExList.Add(new BotIntentQuestionTypeEx
                    //        {
                    //            Content = question
                    //        });
                    //    });

                    //    botIntentTypeExList.Add(new BotIntentTypeEx
                    //    {
                    //        IntentName = intentImportDto.IntentName,
                    //        ResponseText = intentImportDto.Response,
                    //        Question = botIntentQuestionTypeExList.ToArray()
                    //    });
                    //}
                    //if (botIntentTypeExList.Count > 0)
                    //{
                    //    BotImportDataQueue botImportDataQueue = new BotImportDataQueue
                    //    {
                    //        SiteId = botDto.SiteId,
                    //        BotId = botDto.Id,
                    //        AppId = botDto.BotEngineAppId,
                    //        BotImportData = new BotImportDataEx
                    //        {
                    //            Bot = new BotTypeEx
                    //            {
                    //                Language = botDto.Language,
                    //                Category = new BotCategoryTypeEx[] {
                    //                 new BotCategoryTypeEx{
                    //                     Intent=botIntentTypeExList.ToArray()
                    //                 }
                    //             }
                    //            }
                    //        }
                    //    };
                    //    apiResult = await botApiService.ImportBot(botImportDataQueue);
                    //}
                }

            }
            catch (Exception e)
            {
                apiResult.IsSuccess = false;
                apiResult.Error = new ErrorInfo
                {
                    Message = e.Message
                };
                LogHelper.Error(JsonConvert.SerializeObject(e));
            }
            finally
            {

            }
            return apiResult;
        }
        private BotImportDataQueue GetBotImportDataQueue(Chatbot bot, List<IntentImportDto> intentImportDtoList)
        {
            IEntityDomainService entityDomainService = _container.Resolve<IEntityDomainService>();
            IIntentDomainService intentDomainService = _container.Resolve<IIntentDomainService>();
            IIntentQuestionDomainService intentQuestionDomainService = _container.Resolve<IIntentQuestionDomainService>();
            IIntentQuestionSelectedKeywordDomainService intentQuestionSelectedKeywordDomainService = _container.Resolve<IIntentQuestionSelectedKeywordDomainService>();

            BotImportDataQueue botImportDataQueue = null;
            List<BotEntityTypeEx> botEntityTypeExList = new List<BotEntityTypeEx>();
            List<BotIntentTypeEx> botIntentTypeExList = new List<BotIntentTypeEx>();
            List<IntentImportDto> exsitsIntentList = intentImportDtoList.Where(a => a.Mode == EnumImportMode.increment && a.IfExsitsIntent == true).ToList();
            List<IntentImportDto> notExsitsIntentList = intentImportDtoList.Except(exsitsIntentList).ToList();
            foreach (IntentImportDto intentImportDto in notExsitsIntentList)
            {
                List<BotIntentQuestionTypeEx> botIntentQuestionTypeExList = new List<BotIntentQuestionTypeEx>();

                string[] questions = Utils.TextSplitTrim(intentImportDto.VisitorQuestions, "|");
                Array.ForEach(questions, (question) =>
                {
                    botIntentQuestionTypeExList.Add(new BotIntentQuestionTypeEx
                    {
                        Content = question
                    });
                });

                botIntentTypeExList.Add(new BotIntentTypeEx
                {
                    IntentName = intentImportDto.IntentName,
                    ResponseText = intentImportDto.Response,
                    Question = botIntentQuestionTypeExList.ToArray()
                });
            }
            if (exsitsIntentList != null && exsitsIntentList.Count > 0)
            {
                var botEntityList = entityDomainService.GetAllByBotId(bot.Id);
                botEntityTypeExList = Mapper.Map<List<BotEntityTypeEx>>(botEntityList);

                foreach (IntentImportDto intentImportDto in exsitsIntentList)
                {
                    var botIntents = intentDomainService.GetByName(bot.Id, intentImportDto.IntentName);
                    if (botIntents != null && botIntents.Id != Guid.Empty)
                    {
                        BotIntentTypeEx botIntentTypeEx = Mapper.Map<BotIntentTypeEx>(botIntents);
                        botIntentTypeExList.Add(botIntentTypeEx);

                        List<BotIntentQuestionTypeEx> botIntentQuestionTypeExList = new List<BotIntentQuestionTypeEx>();
                        var intentQuestionsList = intentQuestionDomainService.GetByIntentId(botIntents.Id);

                        //增量Qeustion
                        string[] incrementQuestionList = intentImportDto.VisitorQuestions.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string incrementQuestion in incrementQuestionList)
                        {
                            botIntentQuestionTypeExList.Add(new BotIntentQuestionTypeEx
                            {
                                Content = incrementQuestion
                            });
                        }

                        //原有Question
                        if (intentQuestionsList != null)
                        {
                            foreach (var intentQuestions in intentQuestionsList)
                            {
                                BotIntentQuestionTypeEx botIntentQuestionTypeEx = Mapper.Map<BotIntentQuestionTypeEx>(intentQuestions);
                                botIntentQuestionTypeExList.Add(botIntentQuestionTypeEx);

                                List<BotIntentQuestionEntityTypeEx> botIntentQuestionEntityTypeExList = new List<BotIntentQuestionEntityTypeEx>();
                                var intentQuestionEntitiesList = intentQuestionSelectedKeywordDomainService.GetByQuestionId(intentQuestions.Id);
                                if (intentQuestionEntitiesList != null)
                                {
                                    foreach (var intentQuestionEntities in intentQuestionEntitiesList)
                                    {
                                        BotIntentQuestionEntityTypeEx botIntentQuestionEntityExType = Mapper.Map<BotIntentQuestionEntityTypeEx>(intentQuestionEntities);

                                        var botEntities = botEntityList.FirstOrDefault(a => a.Id == intentQuestionEntities.EntityId);
                                        botIntentQuestionEntityExType.EntityName = botEntities?.Name;

                                        botIntentQuestionEntityTypeExList.Add(botIntentQuestionEntityExType);
                                    }

                                }
                                botIntentQuestionTypeEx.QuestionEntity = botIntentQuestionEntityTypeExList.ToArray();
                            }
                        }
                        botIntentTypeEx.Question = botIntentQuestionTypeExList.ToArray();

                        List<BotEntityCollectionPromptTypeEx> botEntityCollectionPromptTypeExList = new List<BotEntityCollectionPromptTypeEx>();
                        var entityCollectionPromptsList = intentDomainService.GetPromptsByIntentId(botIntents.Id);

                        if (entityCollectionPromptsList != null)
                        {
                            foreach (var entityCollectionPrompts in entityCollectionPromptsList)
                            {
                                //设置EntityName
                                BotEntityCollectionPromptTypeEx botEntityCollectionPromptTypeEx = Mapper.Map<BotEntityCollectionPromptTypeEx>(entityCollectionPrompts);

                                var botEntities = botEntityList.FirstOrDefault(a => a.Id == entityCollectionPrompts.EntityId);
                                botEntityCollectionPromptTypeEx.EntityName = botEntities?.Name;
                                botEntityCollectionPromptTypeExList.Add(botEntityCollectionPromptTypeEx);
                            }
                        }
                        botIntentTypeEx.EntityCollectionPrompts = botEntityCollectionPromptTypeExList.ToArray();
                    }

                }
            }
            if (botIntentTypeExList.Count > 0)
            {
                botImportDataQueue = new BotImportDataQueue
                {
                    SiteId = bot.SiteId,
                    BotId = bot.Id,
                    AppId = bot.DialogFlowProjectId,
                    OperateType = EnumOperateType.importIntent,
                    BotImportData = new BotImportDataEx
                    {
                        Bot = new BotTypeEx
                        {
                            Language = bot.Language,
                            Category = new BotCategoryTypeEx[] {
                                new BotCategoryTypeEx{
                                    Intent =botIntentTypeExList.ToArray()
                                }
                            },
                            Entity = botEntityTypeExList.ToArray()
                        }
                    }
                };
            }
            return botImportDataQueue;

        }
        private string InitDataWithBotEngine(IntentImportDataQueue intentImportDataQueue, Chatbot bot)
        {
            string errorMessage = "";
            try
            {
                //从luis取出intent，entity数据将id的值设置到对应的数据中，以便数据库存储
                IBotApiService botApiService = _container.Resolve<IBotApiService>();
                var botDto = Mapper.Map<BotDto>(bot);
                List<IntentModelAggregate> intentModelAggregateList = botApiService.GetIntentList(botDto).Result;
                if (intentModelAggregateList != null)
                {
                    SetIntentIdForImportData(intentModelAggregateList, intentImportDataQueue, bot);
                }

            }
            catch (Exception e)
            {
                errorMessage = e.Message;
                LogHelper.Error(JsonConvert.SerializeObject(e));
            }
            finally
            {

            }
            return errorMessage;

        }
        private void SetIntentIdForImportData(List<IntentModelAggregate> intentModelAggregateList, IntentImportDataQueue intentImportDataQueue, Chatbot bot)
        {           
            List<IntentImportDto> noErrorIntentImportDto = intentImportDataQueue.IntentImportDtoList.Where(a => a.ErrorMsg.Length == 0).ToList();

            if (intentModelAggregateList != null)
            {

                foreach (IntentImportDto intentImportDto in noErrorIntentImportDto)
                {
                    string intentId = intentModelAggregateList.FirstOrDefault(a => a.IntentModel.IntentName == intentImportDto.IntentName)?.IntentModel.Id;

                    if (bot.EngineType == EnumBotType.comm100OwnBot)
                    {//2019.6.20 comm100OwnBot
                        intentId = Guid.NewGuid().ToString();
                    }

                    if (!string.IsNullOrEmpty(intentId))
                    {
                        intentImportDto.Id = string.Format("{0}", intentId);
                    }
                    else
                    {
                        intentImportDto.ErrorMsg = string.Format("Cannot find intent '{0}' an application version with the version.", intentImportDto.IntentName);
                    }

                }
            }
            else
            {
                foreach (IntentImportDto intentImportDto in noErrorIntentImportDto)
                {
                    intentImportDto.ErrorMsg = string.Format("Cannot find any intent an application version with the version.");
                }
            }
        }

        private IntentImportDataQueue GetImportDataQueue(Guid jobId, string fileName, Chatbot bot, EnumImportMode mode, out BackgroundJob backgroundJob)
        {
            backgroundJob = null;
            IntentImportDataQueue intentImportDataQueue = null;

            IBackgroundJobDomainService backgroundJobDomainService = _container.Resolve<IBackgroundJobDomainService>();
            backgroundJob = backgroundJobDomainService.Get(jobId);
            
            //string key = jobId.ToString();
            //backgroundJob = Utils.GetMemoryCache<BackgroundJob>(key);

            if (backgroundJob != null)
            {
                OperateEntity operateEntity = JsonConvert.DeserializeObject<OperateEntity>(backgroundJob.Content);
                intentImportDataQueue = JsonConvert.DeserializeObject<IntentImportDataQueue>(Convert.ToString(operateEntity.Content));
            }

            if (intentImportDataQueue == null)
            {
                intentImportDataQueue = new IntentImportDataQueue()
                {
                    ProcessState = EnumOperationStatus.Wait,
                    FileName = fileName,
                    OperationId = jobId.ToString(),
                };

                IntentImportDataQueue newIntentImportDataQueue = new IntentImportDataQueue(intentImportDataQueue);
                newIntentImportDataQueue.ProcessState = EnumOperationStatus.Occupy;
                backgroundJob = CreateImportDataQueue(jobId, fileName, newIntentImportDataQueue, bot, mode);

                //OperateEntity operateEntity = new OperateEntity
                //{
                //    SiteId = bot.SiteId,
                //    BotId = bot.Id,
                //    FilePath = fileName,
                //    OperateType = EnumOperateType.importIntent,
                //    Mode = mode,
                //    Content = newIntentImportDataQueue,
                //};

                ////Utils.SetMemoryCache(operateEntity.operateName, operateEntity);
                //BackgroundJob job = new BackgroundJob 
                //{
                //    Id = jobId,
                //    SiteId = bot.SiteId,
                //    BotId = bot.Id,
                //    Type = EnumOperateType.importIntent,
                //    Attachment = new byte[] { },
                //    Content = JsonConvert.SerializeObject(intentImportDataQueue),
                //    Status = newIntentImportDataQueue.ProcessState,
                //    CreatedTime = DateTime.UtcNow,
                //};
                //backgroundJobDomainService.Create(job);
                //intentImportDataQueue.OperationId = job.Id.ToString();
            }
            else if (intentImportDataQueue.ProcessState != EnumOperationStatus.Occupy)
            {
                IntentImportDataQueue newIntentImportDataQueue = new IntentImportDataQueue(intentImportDataQueue);
                newIntentImportDataQueue.ProcessState = EnumOperationStatus.Occupy;
                SetImportDataQueue(jobId, fileName, newIntentImportDataQueue, bot, mode);
            }
            return intentImportDataQueue;
        }
        private void SetImportDataQueue(Guid jobId, string fileName, IntentImportDataQueue intentImportDataQueue, Chatbot bot, EnumImportMode mode)
        {
            OperateEntity operateEntity = new OperateEntity
            {
                SiteId = bot.SiteId,
                BotId = bot.Id,
                FilePath = fileName,
                OperateType = EnumOperateType.importIntent,
                Mode = mode,
                Content = intentImportDataQueue,
            };
            BackgroundJobUpdateBo job = new BackgroundJobUpdateBo
            {
                Id = jobId,
                SiteId = bot.SiteId,
                BotId = bot.Id,
                Type = EnumOperateType.importIntent,
                Attachment = new byte[] { },
                Content = JsonConvert.SerializeObject(operateEntity),
                Status = intentImportDataQueue.ProcessState,
                CreatedTime = DateTime.UtcNow,
            };
            //string key = jobId.ToString();
            //Utils.SetMemoryCache(key, job);
            IBackgroundJobDomainService backgroundJobDomainService = _container.Resolve<IBackgroundJobDomainService>();
            backgroundJobDomainService.Update(job);
        }
        private BackgroundJob CreateImportDataQueue(Guid jobId, string fileName, IntentImportDataQueue intentImportDataQueue, Chatbot bot, EnumImportMode mode)
        {
            OperateEntity operateEntity = new OperateEntity { 
                SiteId = bot.SiteId,
                BotId = bot.Id,
                FilePath = fileName,
                OperateType = EnumOperateType.importIntent,
                Mode = mode,
                Content = intentImportDataQueue,                
            };
            BackgroundJob job = new BackgroundJob
            {
                Id = jobId,
                SiteId = bot.SiteId,
                BotId = bot.Id,
                Type =  EnumOperateType.importIntent,
                Attachment = new byte[] { },
                Content = JsonConvert.SerializeObject(operateEntity),
                Status = intentImportDataQueue.ProcessState,
                CreatedTime = DateTime.UtcNow,
            };

            IBackgroundJobDomainService backgroundJobDomainService = _container.Resolve<IBackgroundJobDomainService>();
            backgroundJobDomainService.Create(job);

            //string key = jobId.ToString();
            //Utils.SetMemoryCache(key, job);
            return job;
        }
        private string ImportData2Queue(IntentImportDataQueue intentImportDataQueue)
        {
            string errorMessage = "";
            try
            {
                List<IntentImportDto> noErrorIntentImportDto = intentImportDataQueue.IntentImportDtoList.Where(a => a.ErrorMsg.Length == 0).ToList();
                foreach (IntentImportDto intentImportDto in noErrorIntentImportDto)
                {
                    intentImportDataQueue.ImportDataQueue.Enqueue(intentImportDto);
                }

            }
            catch (Exception e)
            {
                errorMessage = e.Message;
                LogHelper.Error(JsonConvert.SerializeObject(e));
            }
            finally
            {

            }
            return errorMessage;
        }

        private string SaveDbForImportData(IntentImportDataQueue intentImportDataQueue, Chatbot bot)
        {
            string errorMessage = "";
            try
            {
                IIntentDomainService intentDomainService = _container.Resolve<IIntentDomainService>();
                IIntentQuestionDomainService intentQuestionDomainService = _container.Resolve<IIntentQuestionDomainService>();
                IIntentAnswerInChannelDomainService intentAnswerInChannelDomainService = _container.Resolve<IIntentAnswerInChannelDomainService>();
                IQuickReplyDomainService quickReplyDomainService = _container.Resolve<IQuickReplyDomainService>();

                //为了前端能够及时收到消息，一次只处理50条
                int index = 0;
                while (intentImportDataQueue.ImportDataQueue.Count > 0)
                {
                    if (index > 50)
                    {
                        break;
                    }
                    else
                    {
                        dynamic data = JsonConvert.DeserializeObject<IntentImportDto>(Convert.ToString(intentImportDataQueue.ImportDataQueue.Dequeue()));

                        if (data != null)
                        {
                            IntentImportDto intentImportDto = data as IntentImportDto;

                            //新增 intent
                            Intent intent = new Intent { 
                                Id= Guid.NewGuid(),
                                CategoryId = intentImportDto.CategoryId,
                                Name = intentImportDto.IntentName,
                                MappingToDialogflowId = intentImportDto.Id,
                                IsDeleted = false,
                            };
                            // 等待修改response 处理

                            if (intentImportDto.Mode == EnumImportMode.increment && intentImportDto.IfExsitsIntent)
                            {
                                //增量模式 且 intent 已经存在
                                intent = intentDomainService.GetByName(bot.Id, intentImportDto.IntentName);
                            }
                            else
                            {
                                intent = intentDomainService.Create(bot.Id,intent);
                            }

                            if (intent != null && intent.Id != Guid.Empty)
                            {
                                //存储Question
                                string[] questions = intentImportDto.VisitorQuestions.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                                bool flag = true;
                                foreach (string question in questions)
                                {
                                    IntentQuestion intentQuestion = new IntentQuestion
                                    {
                                        Id = Guid.NewGuid(),
                                        IntentId = intent.Id,
                                        Content = question,
                                        IsDeleted = false,
                                    };
                                    flag = AddQuestion(intentQuestion,intentQuestionDomainService);
                                    if (!flag)
                                    {
                                        LogHelper.Error(string.Format("Database Save Lable[{0}]", JsonConvert.SerializeObject(intent)));
                                        break;
                                    }
                                    else
                                    {
                                        intentImportDto.ErrorMsg = "success";
                                    }
                                }

                                if (flag)
                                {
                                    intentImportDto.ErrorMsg = "success";
                                }
                                else
                                {
                                    intentImportDto.ErrorMsg = "Database Save Question fail";
                                }

                                if ((intentImportDto.Mode == EnumImportMode.increment && intentImportDto.IfExsitsIntent == false) ||
                                   intentImportDto.Mode == EnumImportMode.overwrite)
                                {
                                    //存储 IntentAnswers
                                    IntentAnswerInChannel intentAnswerInChannel = new IntentAnswerInChannel
                                    {
                                        Id = Guid.NewGuid(),
                                        IntentId = intent.Id,
                                        Channel = "default",
                                        InformationCollectionType = EnumEntityCollectionType.none,
                                        Responses = new List<Response> {
                                            new Response{
                                                Type = EnumAnswerType.text,
                                                TextVariants = JsonConvert.SerializeObject(intentImportDto.Response.Split('|')),
                                                Order = 1,
                                            }
                                        }
                                    };
                                    intentAnswerInChannelDomainService.Create(intentAnswerInChannel);
                                    
                                    if (intentAnswerInChannel != null && intentAnswerInChannel.Id != Guid.Empty)
                                    {

                                    }
                                    else
                                    {
                                        intentImportDto.ErrorMsg = "Database Save Intent Answer fail";
                                    }

                                    //Quick Reply
                                    if (!string.IsNullOrEmpty(intentImportDto.QuickReply))
                                    {
                                        string[] quickReplyArray = intentImportDto.QuickReply.Split(new string[] { Utils.GeneralSeparator }, StringSplitOptions.RemoveEmptyEntries);
                                        string quickReplyText = "";
                                        string quickReplyName = "";

                                        if (quickReplyArray != null &&
                                            (quickReplyArray.Length == 1 || quickReplyArray.Length == 2))
                                        {
                                            quickReplyName = quickReplyArray[0];
                                            quickReplyText = quickReplyArray.Length == 2 ? quickReplyArray[1] : "";

                                            var quickReply = quickReplyDomainService.GetByName(bot.Id, quickReplyName);
                                            if (quickReply != null &&
                                                quickReply.Id != Guid.Empty)
                                            {
                                                Guid quickReplyId = quickReply.Id;

                                                intentAnswerInChannel = new IntentAnswerInChannel
                                                {
                                                    Id = Guid.NewGuid(),
                                                    IntentId = intent.Id,
                                                    Channel = "default",
                                                    InformationCollectionType = EnumEntityCollectionType.none,
                                                    Responses = new List<Response> {
                                                        new Response{
                                                            Type = EnumAnswerType.quickReply,
                                                            QuickReplyId = quickReplyId,
                                                            Order = 2,
                                                        }
                                                    }
                                                };

                                                intentAnswerInChannelDomainService.Create(intentAnswerInChannel);
                                                if (intentAnswerInChannel != null && intentAnswerInChannel.Id != Guid.Empty)
                                                {

                                                }
                                                else
                                                {
                                                    intentImportDto.ErrorMsg = "Database Save Intent Answer fail";
                                                }
                                            }
                                            else
                                            {
                                                LogHelper.Error(string.Format("Database Save Intent[{0}],Quick Reply[{1}] Not Exists.", JsonConvert.SerializeObject(intent), quickReplyName));
                                                intentImportDto.ErrorMsg = "Database Save Intent fail";
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                LogHelper.Error(string.Format("Database Save Intent[{0}]", JsonConvert.SerializeObject(intent)));
                                intentImportDto.ErrorMsg = "Database Save Intent fail";
                            }

                        }
                        index++;
                    }
                }

                if (intentImportDataQueue.ImportDataQueue.Count == 0)
                {
                    intentImportDataQueue.Status = EnumImportHandleStatus.Publish;
                }
                else
                {
                    intentImportDataQueue.Status = EnumImportHandleStatus.Processing;
                }
            }
            catch (Exception e)
            {
                LogHelper.Error(JsonConvert.SerializeObject(e));
                errorMessage = e.Message;
            }
            finally
            {

            }

            return errorMessage;
        }
        private bool AddQuestion(IntentQuestion question, IIntentQuestionDomainService intentQuestionDomainService)
        {
            if (string.IsNullOrWhiteSpace(question.Content) || question.IntentId == Guid.Empty)
                return false;
            return intentQuestionDomainService.Create(question).Id != Guid.Empty;
        }
        private ApiResult GetErrorIntentImportExcelPath(string filePath, List<IntentImportDto> intentImportDtoList, int siteId, Guid jobId)
        {
            ApiResult apiReuslt = new ApiResult { IsSuccess = false };
            try
            {
                string[] arr = filePath.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
                string fileName = string.Format("Failed {0}", arr.LastOrDefault());

                string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadedFiles");
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);
                if (Directory.Exists(path))
                {
                    path = Path.Combine(path, siteId.ToString());
                    if (!Directory.Exists(path))
                        Directory.CreateDirectory(path);
                    if (Directory.Exists(path))
                    {
                        string serverFileName = Path.Combine(path, fileName);
                        path = serverFileName;
                    }
                }

                //写入存在错误信息的数据到Excel
                DataTable errTable = new DataTable();

                errTable.Columns.Add("Category Path");
                errTable.Columns.Add("Intent Name");
                errTable.Columns.Add("Visitor Questions");
                errTable.Columns.Add("Response");
                errTable.Columns.Add("Error Message");

                bool haveErr = false;

                List<IntentImportDto> errorEntityImportDtoList = intentImportDtoList.Where(a => (a.ErrorMsg.Length > 0 && a.ErrorMsg != "success")).ToList();
                foreach (IntentImportDto intentImportDto in errorEntityImportDtoList)
                {
                    haveErr = true;

                    DataRow newRow = errTable.NewRow();
                    errTable.Rows.Add(newRow);
                    newRow["Category Path"] = intentImportDto.CategoryPath;
                    newRow["Intent Name"] = intentImportDto.IntentName;
                    newRow["Visitor Questions"] = intentImportDto.VisitorQuestions;
                    newRow["Response"] = intentImportDto.Response;
                    newRow["Error Message"] = intentImportDto.ErrorMsg;
                }
                List<IntentImportDto> successEntityImportDtoList = intentImportDtoList.Where(a => (a.ErrorMsg.Length > 0 && a.ErrorMsg == "success")).ToList();
                foreach (IntentImportDto intentImportDto in successEntityImportDtoList)
                {
                    DataRow newRow = errTable.NewRow();
                    errTable.Rows.Add(newRow);
                    newRow["Category Path"] = intentImportDto.CategoryPath;
                    newRow["Intent Name"] = intentImportDto.IntentName;
                    newRow["Visitor Questions"] = intentImportDto.VisitorQuestions;
                    newRow["Response"] = intentImportDto.Response;
                    newRow["Error Message"] = "";
                }

                if (haveErr)
                {
                    var util = TransferDataFactory.GetUtil(filePath);
                    util.SaveData(errTable, path);

                    //存储到数据库
                    //IBackgroundJobDomainService backgroundJobDomainService = _container.Resolve<IBackgroundJobDomainService>();
                    //BackgroundJob backgroundJob = backgroundJobDomainService.Get(jobId);
                    //backgroundJob.Attachment = File.ReadAllBytes(path);
                    //BackgroundJobUpdateBo backgroundJobUpdateBo = Mapper.Map<BackgroundJobUpdateBo>(backgroundJob);
                    //backgroundJobDomainService.Update(backgroundJobUpdateBo);

                    //var psi = new System.Diagnostics.ProcessStartInfo("hostname");
                    //return $"{psi.Domain}/api/v3/chatbot/images/{Id}";

                    //strResult = string.Format("{0}{1}", masterUrl, currFile.Replace("\\", "/"));
                    //strResult = strResult.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();

                    //strResult = string.Format("{0}/{1}", masterUrl, "api/v2/bot/downloadFile?operationId=" + operationId);
                    
                    apiReuslt.Error = new ErrorInfo {
                        Message = string.Join(",", errorEntityImportDtoList.Select(a=>a.ErrorMsg)),
                    };
                }
                apiReuslt.IsSuccess = true;
            }
            catch (Exception e)
            {
                apiReuslt.IsSuccess = false;
                apiReuslt.Error = new ErrorInfo
                {
                    Message = e.Message
                };
                LogHelper.Error(JsonConvert.SerializeObject(e));
            }
            finally
            {

            }

            return apiReuslt;
        }

        #endregion
    }
}
